/**
 * 
 */
package sailing.worker;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import sailing.excel.ExcelParser;
import sailing.excel.TranslationException;
import sailing.excel.Translator;
import cjlite.logger.Logger;
import cjlite.utils.Strings;

/**
 * @author kevin
 * 
 */
public class FileLoadWorker<T, V> extends FileIOWorker<T, V> {
	private static Logger logger = Logger.thisClass();

	private final String filePath;
	private ExcelParser ep;

	public FileLoadWorker(String path, ExcelParser ep) {
		this.filePath = path;
		this.ep = ep;
	}

	@Override
	protected T doInBackground() throws Exception {
		File file = new File(filePath);
		try {
			this.appendTaskMsg(1, "开始读取文件: " + filePath);
			InputStream is = new FileInputStream(file);
			Workbook wb = WorkbookFactory.create(is);
			is.close();
			this.appendTaskMsg(2, "文件读取完成: " + filePath);

			Translator translator = null;
			try {
				translator = this.ep.getTranslator();
			} catch (Exception e1) {
				this.appendTaskMsg("初始化解析器(" + this.ep.getParserClass().getName() + ")出现错误，参见Log");
				return null;
			}

			this.appendTaskMsg(3, "开始解析... ...");

			int sheetNum = wb.getNumberOfSheets();
			int perc = sheetNum == 0 ? 97 : 97 / sheetNum;
			for (int i = 0; i < sheetNum; i++) {
				this.parseSheet(i, wb.getSheetAt(i), translator, perc);
				// this.incresProgress(perc);
			}
			this.countDown();
			this.done();
			this.appendTaskMsg(100, "解析完成!");
		} catch (Throwable e) {
			this.countDown();
			this.done();
			logger.error("加载文件【{0}】的时候出现错误：", e, filePath);
		}

		return null;
	}

	private void parseSheet(int i, Sheet sheet, Translator translator, int perc) {
		this.appendTaskMsg("开始解析Sheet(" + sheet.getSheetName() + ")");
		int start = sheet.getFirstRowNum();
		int end = sheet.getLastRowNum();
		
		if(end==0){
			this.appendTaskMsg("Sheet(" + sheet.getSheetName() + ")没有数据");
			return;
		}
		
		
		int rowN=end-start+1;

		int rowPerc=perc/rowN;

		if (translator == null) {
			return;
		}

		for (int j = start; j <= end; j++) {
			if (translator.wouldParse(j)) {
				Row row = sheet.getRow(j);
				try {
					Object object = this.ep.getNewInstance();
					translator.fromRow(object, row);
					this.ep.addParsedData(object);
					this.incresProgress(rowPerc);
					this.appendTaskMsg("开始解析 sheet("+sheet.getSheetName()+") 行("+(j+1)+") 数据");
				} catch (TranslationException e) {
					StringBuilder sb = new StringBuilder();
					sb.append("解析Sheet(");
					sb.append(sheet.getSheetName());
					sb.append(") rowNum=");
					sb.append(j + 1);
					sb.append(" 出现错误：");
					sb.append(e.getMessage());
					this.appendTaskMsg(sb.toString());
				} catch (Throwable e) {
					logger.error("error on parse Row[{0}] sheet[{1}]", e, j, sheet.getSheetName());
				}
			}
		}
	}

	private void parseRow(Row row) {
		logger.trace("getFirstCellNum={0}", row.getFirstCellNum());
		logger.trace("getLastCellNum={0}", row.getLastCellNum());
		logger.trace("getPhysicalNumberOfCells={0}", row.getPhysicalNumberOfCells());

		int startC = row.getFirstCellNum();
		int endC = row.getLastCellNum();

		StringBuilder sb = new StringBuilder();
		for (int c = startC; c < endC; c++) {
			Cell cell = row.getCell(c);
			if (cell != null) {
				sb.append(cell.getCellType());
			}
		}
	}

	private void setTaskMsg(String msg) {
		logger.trace(msg);
		// pd.setTaskMsg(msg);
	}

	@Override
	public String getWorkerMsg() {
		return Strings.concat("文件：", this.filePath);
	}

	@Override
	public String getTerminationMsg() {
		return "文件读取还没有解析完成，确定要取消？";
	}

}
